package fr.gla.hibtracker.historique.collection;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

import org.hibernate.HibernateException;
import org.hibernate.collection.PersistentSet;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.persister.collection.CollectionPersister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.gla.hibtracker.historique.listener.DirtyUpdateListener;

@SuppressWarnings("serial")
public class HistoricCollection extends PersistentSet {

	private static final Logger LOGGER = LoggerFactory.getLogger(DirtyUpdateListener.class);

	transient ThreadLocal<Set> snapshot = new ThreadLocal<Set>();

	public HistoricCollection() {}

	public HistoricCollection(SessionImplementor session, Set set) {
		super(session, set);
	}

	public HistoricCollection(SessionImplementor session) {
		super(session);
	}

	@Override
	public boolean endRead() {
		boolean endRead = super.endRead();
		snapshot.set(new HashSet(set));
		return endRead;
	}

	@Override
	public void preInsert(CollectionPersister persister)
			throws HibernateException {
		super.preInsert(persister);
		if(isDirty()){
			EventSource eventSource = (EventSource) getSession();
			HistoriqueCollectionHelper historiqueCollectionHelper = new HistoriqueCollectionHelper(eventSource,getRole(),getOwner(),getValue(snapshot.get()),getValue((Set)getValue()));
			historiqueCollectionHelper.historise();
		}else{
			if(LOGGER.isDebugEnabled()){
				LOGGER.debug("Collection "+ getRole()+" is not modified");
			}
		}
		snapshot.set(null);
	}



	private String getValue(Set set){
		StringBuilder builder = new StringBuilder();
		Set<String> orderedSet = new TreeSet<String>();
		if(set != null){
			for(Object obj : set){
				orderedSet.add(obj.toString());
			}
		}
		for(String value : orderedSet) {
            builder.append(value+"\n");
        }
		if(builder.length() != 0) {
            builder.delete(builder.length()-1, builder.length());
        }
		return builder.toString();
	}

}
